﻿
using Xacml.Core.Interfaces;
using Xacml.Core.Runtime;

namespace Xacml.Core.Runtime.Functions
{
  public abstract class BaseUnion : FunctionBase, ITypeSpecificFunction
  {
    public override IDataType Returns
    {
      get
      {
        return (IDataType) DataTypeDescriptor.Bag;
      }
    }

    public override IDataType[] Arguments
    {
      get
      {
        return new IDataType[2]
        {
          (IDataType) DataTypeDescriptor.Bag,
          (IDataType) DataTypeDescriptor.Bag
        };
      }
    }

    public abstract IDataType DataType { get; }

    public override EvaluationValue Evaluate(EvaluationContext context, params IFunctionParameter[] args)
    {
      BagValue bagValue = new BagValue(this.DataType);
      IFunction isInFunction = this.DataType.IsInFunction;
      foreach (object obj in args[0].Elements)
      {
        if (!isInFunction.Evaluate(context, (IFunctionParameter) new EvaluationValue(obj, args[0].GetType(context)), (IFunctionParameter) bagValue).BoolValue)
          bagValue.Add((object) new EvaluationValue(obj, args[0].GetType(context)));
      }
      foreach (object obj in args[1].Elements)
      {
        if (!isInFunction.Evaluate(context, (IFunctionParameter) new EvaluationValue(obj, args[1].GetType(context)), (IFunctionParameter) bagValue).BoolValue)
          bagValue.Add((object) new EvaluationValue(obj, args[1].GetType(context)));
      }
      return new EvaluationValue((object) bagValue, this.DataType);
    }
  }
}
